#coding=utf-8

# Create your views here.
from django.http import HttpResponse
##from django.template import Context,loader
from postgetter.getpost.models import Forum,Sector,Post,Reply,ImgUrl
from django.shortcuts import render_to_response,get_object_or_404,get_list_or_404,redirect
##from django.db.models import Q
#from django.forms import ModelForm
##from django.forms.models import modelformset_factory

import StringIO
import imghdr
#import timeit
import time
import os
import errno
import datetime
import base64
from math import ceil
import re
import urlparse
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

NR_POST_PER_PAGE=50
NR_REPLY_PER_PAGE=20

IMG_BASE_PATH='/home/kevin/data_bk/bbsimgfile/'
FILEEXT={'jpeg':'jpg','png':'png','gif':'gif','jpg':'jpg','bmp':'bmp'}

def index(request):
	u'''首页，查询符合条件的主题
	支持多个关键字and(空格分割)，支持not(-开头)，不支持or
	'''
	pl,p,total,max_page,item_from=None,1,0,1,1
	q=request.GET.get('q','')
	if q and q!='':
		print 'q=',q
		p=int(request.GET.get('page',1))
		klist=q.split()
		for i,k in enumerate(klist):
			if i==0:
				if k.startswith('-'):
					pl=Post.objects.exclude(title__icontains=k[1:])
				else:
					pl=Post.objects.filter(title__icontains=k)
			else:
				if k.startswith('-'):
					pl=pl.exclude(title__icontains=k[1:])
				else:
					pl=pl.filter(title__icontains=k)
		pl=pl.order_by('-crt_date')
##		pl=Post.objects.filter(title__icontains=q).order_by('-crt_date')
		total=len(pl)
		max_page=int(ceil(total/float(NR_POST_PER_PAGE)))
		if p>max_page:
			p=max_page
		if total!=0:
			pl=pl[NR_POST_PER_PAGE*(p-1):NR_POST_PER_PAGE*(p-1)+NR_POST_PER_PAGE]
			item_from=NR_POST_PER_PAGE*(p-1)

##		print ('max_page=%d'%max_page)
	else:
		print 'no q'

	# 去掉 querystring 中的"page="
	qs=request.META['QUERY_STRING']
	pPage=re.compile('&page=\d+|\Apage=\d+&',re.I)
	qs=pPage.sub('',qs)
##	print('pl:%d,q=%s,page=%d,total=%d,max_page=%d'%(0 if not pl else len(pl),q,p,total,max_page))
	return render_to_response('index.html',{'pl':pl,'q':q,'qs':qs,'page':p,'item_from':item_from,'total':total,'max_page':max_page})

def viewPost(request,post_id,page_from=1,nr_per_page=10):
	u'''显示某个主题'''
	page_from=int(page_from)
##	print('page_from=%s'%(page_from,))
	p=get_object_or_404(Post,pk=post_id)

	rl=get_list_or_404(Reply,post=p)
	total=len(rl)
	max_page=int(ceil(total/float(NR_REPLY_PER_PAGE)))
	if page_from>max_page:
		page_from=max_page
	# 将 locate_id 转换为 int 后再排序
	rl.sort(key= lambda x:int(x.locate_id))

	rl=rl[NR_REPLY_PER_PAGE*(page_from-1):NR_REPLY_PER_PAGE*(page_from-1)+NR_REPLY_PER_PAGE]
	item_from=NR_REPLY_PER_PAGE*(page_from-1)
	return render_to_response('post.html',{'post':p,'rl':rl,'page':page_from,'item_from':item_from,'total':total,'max_page':max_page})
##	t=loader.get_template('post.html')
##	c=Context({'post':p,'rl':rl,'page':page_from,'item_from':item_from,'total':total,'max_page':max_page})
##	return HttpResponse(t.render(c))

def viewPostList(request):
	u'''按种类/最近更新时间/发表时间/数量 等条件返回主题列表'''
	sectors=None
	pl,total,item_from,max_page,actual_total=None,0,1,1,0
	page_from=int(request.GET.get('page',1))
	kind_s=''
	kind=request.GET.getlist('kind')
##	print('kind=%s'%(kind,))
	if kind:
		# 过滤无效id
		kind_ids=(x for x in kind if Sector.objects.filter(id=x).exists())
		kind_objs=Sector.objects.filter(id__in=kind_ids)
		kind_s=','.join((x.name for x in kind_objs))
	else:
		kind_objs=Sector.objects.none()
	upd_or_crt=request.GET.get('datetype','crt') # 默认 crt
	since=int(request.GET.get('since',1))
	limit=int(request.GET.get('limit',0))
	sectors=Sector.objects.all()

	if upd_or_crt=='upd':
		if since:
			pl=Post.objects.filter(upd_date__gt=datetime.date.today()-datetime.timedelta(days=since)).filter(sector__in=kind_objs).order_by('-upd_date')
		else:
			pl=Post.objects.filter(sector__in=kind_objs).order_by('-upd_date')
	elif upd_or_crt=='crt':
		if since:
			pl=Post.objects.filter(crt_date__gt=datetime.date.today()-datetime.timedelta(days=since)).filter(sector__in=kind_objs).order_by('-crt_date')
		else:
			pl=Post.objects.filter(sector__in=kind_objs).order_by('-crt_date')
	else:
		pl=[]
		print('not upd or crt (%s),do nothing'%(upd_or_crt,))

	if pl:
		actual_total=len(pl)

	if limit>0 and pl:
##		print('actual len(pl)=%d, but limit=%d'%(actual_total,limit))
		pl=pl[:limit]
##		print('now len(pl)=%d'%(limit,))
	total=len(pl)
	max_page=int(ceil(total/float(NR_POST_PER_PAGE)))
	if page_from>max_page:
		page_from=max_page

	# 分页
	if total!=0:
		pl=pl[NR_POST_PER_PAGE*(page_from-1):NR_POST_PER_PAGE*(page_from-1)+NR_POST_PER_PAGE]
		item_from=NR_POST_PER_PAGE*(page_from-1)

	# 去掉 querystring 中的"page="
	qs=request.META['QUERY_STRING']
	pPage=re.compile('&page=\d+|\Apage=\d+&',re.I)
	qs=pPage.sub('',qs)


	print('kind=%s, upd_or_crt=%s,since=%d,limit=%d'%(kind_s,upd_or_crt,since,limit))
	return render_to_response('postlist.html',{'pl':pl,'qs':qs,'actual_total':actual_total,'sectors':sectors,'kind':kind_objs,'upd_or_crt':upd_or_crt,'since':since,'limit':limit,'page':page_from,'max_page':max_page,'item_from':item_from,'total':total})


def dispic(request,url):
	u'''根据url显示图片文件'''
	if request.META['QUERY_STRING']: # add query_string if present
		url='?'.join((url,request.META['QUERY_STRING']))
	rawurl=url
##	print 'url=%s'%url

	def _tryDecode(data):
		u'''尝试decode数据data
		'''
		for x in ('utf-8','gb18030','gb2312','big5'):
			try:
				d=data.decode(x)
				return d
			except UnicodeDecodeError as e:
				pass

		if len(data)==1:
			try:
				data=unichr(ord(data))
			except Exception as e:
				pass

		print('can\'t deocde, return unchanged data! len=%d, begin 100 chars:%s'%(len(data),repr(data[:100])))
		return data

	# pre process url
	# unquote chars like %E5%88%98%E5%BC%BA
	url=re.sub('(?:(?:%[0-9A-Za-z]{2,3})+)+?',lambda x:self._tryDecode(urllib.unquote(x.group().encode('gbk'))),url)
	# exceed db field length limit
	if len(url)>255:
		print('got long url %d, %s'%(len(x),url[:100]))
		return redirect(rawurl,permanent=True)
	# remove tag
	premovetag=re.compile('(<.*?>)',re.M|re.S)
	url=premovetag.sub('',url)
	sr=urlparse.urlsplit(url)
	if sr.scheme not in ('http','https'):
		print('bad url %s'%(url,))
		return redirect(rawurl,permanent=True)

##	print('processed url= %s'%(url,))
	try:
		iurl=ImgUrl.objects.select_related('img').get(url=url)#,img__isnull=False)
	except ImgUrl.DoesNotExist:
		print ('!!!!!!!!!!!!! %s not found in imgurl\n\t%s'%(url,rawurl))
		# redirect
		return redirect(url,permanent=True)
	else:
		imagetype=None
		s=StringIO.StringIO()
		if iurl.img:
			filepath=os.path.join(os.path.join(IMG_BASE_PATH,iurl.img.filemd5[:2]),
				'.'.join((iurl.img.filemd5,FILEEXT[iurl.img.ext])))
##			print ('%s ==> %s ~~~~~~~~'%(url,filepath))
			try:
				with open(filepath,'rb') as f:
					s.write(f.read())
			except IOError	as e:
				if e.errno==errno.ENOENT:
					print('!!!!!!!  file not found %s for %s!'%(filepath,rawurl))
					return redirect(url,permanent=True)
				else:
					print e
			else:
				imagetype='/'.join(('image',iurl.img.ext))
		else:
			print 'id=%d, img_id is null.'%iurl.id
			return redirect(url,permanent=True)
##			try:
##				b=time.clock()
##				imagetype=imghdr.what('',s.getvalue())
##				e=time.clock()
##				if imagetype:
##					imagetype='image/'+imagetype
##				else: # imghdr return None
##					imagetype='image/jpeg'
##
##				print 'time %f' % (e-b)
##			except Exception,e:
##				print 'check file type error! %s'%e
##				imagetype='image/jpeg'

		return HttpResponse(s.getvalue(),mimetype=imagetype)
